home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World's Largest Collection of Windows Software
/
The World's Largest Collection of Windows Software - Disc 1.iso
/
connect
/
_j2
/
wvnsc926
/
shellsor.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-09-21
|
4KB
|
114 lines
/*
*
* $Id: shellsor.c 1.8 1994/09/03 01:08:03 rushing Exp $
* $Log: shellsor.c $
* Revision 1.8 1994/09/03 01:08:03 rushing
* define huge away for win32
*
* Revision 1.7 1994/09/02 23:50:14 rushing
* shellsort is now huge
*
* Revision 1.6 1993/12/08 01:28:38 rushing
* new version box and cr lf consistency
*
* Revision 1.5 1993/07/08 19:41:06 rushing
* fixed unsigned bug again. strange.
*
* Revision 1.4 1993/07/06 21:09:09 cnolan
* win32 support
*
* Revision 1.2 1993/06/28 17:53:24 rushing
* fixed compiler warnings
*
* Revision 1.1 1993/02/16 20:53:50 rushing
* Initial revision
*
*
*/
/* Shellsort is a variation on Insertion Sort that is virtually unbeatable
* on small data sets. Insertion Sort is slow because it only exchanges
* adjacent elements. Shellsort circumvents this by allowing the exchange
* of elements that are farther apart. It works by first performing Insertion
* Sort on subsets of the data. For example, Shellsort might first sort
* the set of elements 1, 6, 11, 16... relative to each other--the effect
* is that the elements in that subset are moved much closer to their final
* positions. At first the sets are wide-spread, perhaps every fortieth
* element. Then it repeats using a tighter set, perhaps every fourteenth
* element, then every fourth element. Each of these passes is much cheaper
* than a traditional Insertion Sort pass. The effect of the passes is that
* the data set is mutated to be in "almost sorted" order. The final insertion
* sort pass can then go very quickly because insertion sort does very well on
* almost sorted data. In other words, at first the elements take large leaps
* to the general location they belong and successively smaller steps move the
* element to its precise place. I call this algorithm "inscrutable sort"
* because even after having coded the algorithm, I still have trouble
* following the animation. No one has been able to analyze this algorithm
* rigorously; the functional form of the running time is conjectured to be
* O(N^1.25). Shellsort may be a bit mysterious, but it is an good general
* purpose sort since it has excellent performance and the code you must write
* is only slightly more complex than Insertion Sort.
*
* Author: Julie Zelenski, NeXT Developer Support
* You may freely copy, distribute and reuse the code in this example.
* NeXT disclaims any warranty of any kind, expressed or implied, as to
* its fitness for any particular use. qsort
*/
#ifdef WIN32
#include <windef.h>
#endif
#include <stdio.h>
#include <string.h>
#ifdef WIN32
#define __far far
#define huge far
#define __near near
#endif
#define memSwap(a,b,unused) tmp = *(char huge * huge *)(a); \
*(char huge * huge *)(a) = *(char huge * huge *)(b); *(char huge * huge *)(b) = tmp;
void
ShellSort (void huge * huge * base,
size_t nElements,
size_t width,
int (*compare) (void const huge *elem1, void const huge * elem2))
{
#define STRIDE_FACTOR 3
unsigned int c, stride;
int d;
char far *tmp;
int found;
stride = 1;
while (stride <= nElements)
stride = stride * STRIDE_FACTOR + 1;
while (stride > (STRIDE_FACTOR - 1))
{
stride = stride / STRIDE_FACTOR;
for (c = stride; c < nElements; c++)
{
found = 0;
d = c - stride;
while ((d >= 0) && !found)
{
if (compare ((char huge *) base + (d + stride) * width, (char huge *) base + d * width) < 0)
{
memSwap ((char huge *) base + (d + stride) * width, (char huge *) base + d * width, width);
d -= stride;
}
else
{
found = 1;
}
}
}
}
}